<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>wfs综合操作</title>
  <link rel="stylesheet" href="../js/lib/ol4.6.4/ol.css" type="text/css">
</head>
<body>
<button id="insert">添加</button>
<button id="update">修改</button>
<button id="delete">删除</button>
<button id="end">结束操作</button>
<div id="map"></div>
</body>
<script src="../js/lib/ol4.6.4/ol.js"></script>
<script src="../js/lib/jquery/jquery-3.3.1.min.js"></script>
<script>
  // 服务配置，命名空间、图层、服务地址等
  var geoserverData = {
    wsName: 'test',
    uri: 'http://www.openplans.org/test',
    wfsURL: 'http://localhost:8085/geoserver/wfs?',
    layer: 'port'
  }

  //测试数据 添加WFS数据  添加所有
  var wfsSource = new ol.source.Vector({
    format: new ol.format.GeoJSON(),
    url: function (extent) {
      return (
              geoserverData.wfsURL + 'service=WFS&version=1.1.0&request=GetFeature&typeName=' +
              geoserverData.wsName + ":" +
              geoserverData.layer + '&' + 'outputFormat=application/json&srsname=EPSG:4326&bbox=' +
              extent.join(',') + ',EPSG:4326');
    },
    strategy: ol.loadingstrategy.bbox
  });

  let wfsLayer = new ol.layer.Vector({
    title: 'add Layer',
    source: wfsSource
  })

  var layers = [
    new ol.layer.Tile({
      source: new ol.source.XYZ({
                    url: "https://tile-a.openstreetmap.fr/hot/{z}/{x}/{y}.png"
                })
    }),wfsLayer
  ];

  var map = new ol.Map({
    target: 'map',
    layers: layers,
    view: new ol.View({
      projection: "EPSG:4326",
      center: [114, 31],
      zoom: 4
    })
  });

  map.on('pointermove', function(evt) {
    if(map.hasFeatureAtPixel(evt.pixel)){
      $(map.getTargetElement()).css("cursor", "pointer");
    }else{
      $(map.getTargetElement()).css("cursor", "default");
    }
  });

  let select = new ol.interaction.Select({
    layers:[wfsLayer],
    style: new ol.style.Style({
      image: new ol.style.Circle({
        radius: 8,
        fill: new ol.style.Fill({
          color: "#f00"
        })
      })
    })
  });

  let edit = new ol.interaction.Modify({
    features: select.getFeatures()
  });

  var draw = new ol.interaction.Draw({
    source:new ol.source.Vector({
      features:[]
    }),
    type:'Point',
    freehand: false,//自由手绘,
    stopClick: true
  });

  map.addInteraction(select);
  map.addInteraction(edit);
  map.addInteraction(draw);
  edit.setActive(false);
  draw.setActive(false);
  select.setActive(false);

  $("#insert").on("click", function () {
    select.setActive(false)
    edit.setActive(false)
    draw.setActive(true);
  });
  draw.on("drawend", function(e){
    var feature = e.feature;
    sendWFS(feature, "insert");
  });

  $("#update").on("click", function () {
    draw.setActive(false)
    edit.setActive(true);
    select.setActive(true);
  });

  $("#delete").on("click", function () {
    draw.setActive(false)
    edit.setActive(false)
    select.setActive(true);
  });
  select.on("select", function (e) {
    var features= e.selected;
    if(features.length>0){
      let feature = features[0];
      if (!edit.getActive()){
        sendWFS(feature, "delete");
      }
    }
  });

  edit.on("modifyend", function (e) {
    // 把修改完成的feature暂存起来
    var features = e.features;
    var feature = features.item(0);
    sendWFS(feature, "update");
  });

  $("#end").on("click", function () {
    draw.setActive(false)
    select.setActive(false)
    edit.setActive(false)
  });

  function sendWFS(feature, type) {
    //发送WFS 请求 ，type 分别为insert update delect
    // 1、构造Feature
    let ft = feature.clone()
    // 更新操作必须要有id
    let id = feature.getId()
    let properties = ft.getProperties()
    var featObject;
    var WFSTSerializer = new ol.format.WFS();
    var _this = geoserverData;
    let options = {
      featureNS: _this.uri,
      featurePrefix: _this.wsName, //工作空间名称
      featureType: _this.layer, //图层名称
      srsName: 'EPSG:4326'
    };
    if (type === "insert") {
      properties.address="测试要素添加"
      properties.name="添加"
      properties.porttype="wnm添加"
      properties.province="wnm添加"
      let coordinates = ft.getGeometry().getCoordinates()
      properties.lng = coordinates[0]
      properties.lat = coordinates[1]
      ft.setProperties(properties)

      let geom = ft.getGeometry().clone()
      geom.applyTransform((flatCoordinates, flatCoordinates2, stride) => {
        for (var j = 0; j < flatCoordinates.length; j += stride) {
          var y = flatCoordinates[j]
          var x = flatCoordinates[j + 1]
          flatCoordinates[j] = x
          flatCoordinates[j + 1] = y
        }
      })
      ft.setGeometryName('geom') // postgis字段为geom、shp字段名为the_geom
      ft.setGeometry(geom)

      featObject = WFSTSerializer.writeTransaction([ft], null, null, options);
    } else if (type === "update") {
      ft.setId(id)
      properties.address = "测试要素修改"
      properties.name = "修改"

      let coordinates = ft.getGeometry().getCoordinates()
      properties.lng = coordinates[0]
      properties.lat = coordinates[1]
      ft.setProperties(properties)

      ft.getGeometry().applyTransform((flatCoordinates, flatCoordinates2, stride) => {
        for (var j = 0; j < flatCoordinates.length; j += stride) {
          var y = flatCoordinates[j]
          var x = flatCoordinates[j + 1]
          flatCoordinates[j] = x
          flatCoordinates[j + 1] = y
        }
      })
      ft.setGeometryName('geom')// postgis字段为geom、shp字段名为the_geom

      featObject = WFSTSerializer.writeTransaction(null, [ft], null, options);
    } else if (type === "delete") {
      ft.setId(id)
      featObject = WFSTSerializer.writeTransaction(null, null, [ft], options);
    }
    var serializer = new XMLSerializer();
    var featString = serializer.serializeToString(featObject);
    $.ajax({
      url: geoserverData.wfsURL,
      type:"POST",
      data: featString,
      contentType: 'text/xml',
      success: function (req) {
        console.log(type+"操作成功！")
        wfsSource.changed();
      },
      error: function (e) {
        alert(type+"操作失败！"+e)
      }
    });
  }


</script>
</html>
